package com.xx.web.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.yulichang.toolkit.JoinWrappers;
import com.xx.common.constant.Constants;
import com.xx.common.exception.ServiceException;
import com.xx.utils.base.MPageUtils;
import com.xx.utils.redis.RedisUtil;
import com.xx.web.domain.dto.EnvDto;
import com.xx.web.domain.entity.EarlyWarningRule;
import com.xx.web.domain.entity.NavigationEnv;
import com.xx.web.domain.entity.NavigationEnvType;
import com.xx.web.domain.vo.InnerNavigationEnvVo;
import com.xx.web.mapper.EarlyWarningRuleMapper;
import com.xx.web.mapper.NavigationEnvMapper;
import com.xx.web.mapper.NavigationEnvTypeMapper;
import com.xx.web.service.INavigationEnvService;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.util.*;

/**
 * <p>
 * 通航环境 服务实现类
 * </p>
 *
 * @author xx
 * @since 2023-04-24
 */
@Service
@RequiredArgsConstructor
public class NavigationEnvServiceImpl extends ServiceImpl<NavigationEnvMapper, NavigationEnv> implements INavigationEnvService {

    private final NavigationEnvMapper mapper;

    private final NavigationEnvTypeMapper envTypeMapper;

    private final EarlyWarningRuleMapper ruleMapper;
    private final RedisUtil redisUtil;

    /**
     * 通航环境分页列表
     *
     * @param navigationEnv 根据需要进行传值
     * @return
     */
    @Override
    public IPage<NavigationEnv> page(NavigationEnv navigationEnv) {

        QueryWrapper<NavigationEnv> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda()
                // 通航环境id
                .eq(navigationEnv.getId() != null, NavigationEnv::getId, navigationEnv.getId())
                // 环境名称
                .eq(StringUtils.hasLength(navigationEnv.getName()), NavigationEnv::getName, navigationEnv.getName())
                // 通航环境类型
                .eq(navigationEnv.getEnvType() != null, NavigationEnv::getEnvType, navigationEnv.getEnvType())
                .eq(navigationEnv.getEnvTypeId() != null, NavigationEnv::getEnvTypeId, navigationEnv.getEnvTypeId())
                // 状态（1正常 0停用）
                .eq(navigationEnv.getStatus() != null, NavigationEnv::getStatus, navigationEnv.getStatus())
                // 边框类型
                .eq(navigationEnv.getBorderType() != null, NavigationEnv::getBorderType, navigationEnv.getBorderType())
                // 边框颜色
                .eq(!StringUtils.isEmpty(navigationEnv.getBorderColor()), NavigationEnv::getBorderColor,
                        navigationEnv.getBorderColor())
                .eq(!StringUtils.isEmpty(navigationEnv.getGroup()), NavigationEnv::getGroup, navigationEnv.getGroup())
                // 边框宽度
                .eq(navigationEnv.getBorderWidth() != null, NavigationEnv::getBorderWidth,
                        navigationEnv.getBorderWidth())
                // 填充颜色
                .eq(!StringUtils.isEmpty(navigationEnv.getFillColor()), NavigationEnv::getFillColor,
                        navigationEnv.getFillColor())
                // 图标
                .eq(!StringUtils.isEmpty(navigationEnv.getIcon()), NavigationEnv::getIcon, navigationEnv.getIcon())
                // 区域
                .eq(!StringUtils.isEmpty(navigationEnv.getRegions()), NavigationEnv::getRegions,
                        navigationEnv.getRegions())
                // 创建者
                .eq(!StringUtils.isEmpty(navigationEnv.getCreateBy()), NavigationEnv::getCreateBy,
                        navigationEnv.getCreateBy())
                // 创建时间
                .eq(navigationEnv.getGmtCreate() != null, NavigationEnv::getGmtCreate, navigationEnv.getGmtCreate())
                // 更新者
                .eq(!StringUtils.isEmpty(navigationEnv.getUpdateBy()), NavigationEnv::getUpdateBy,
                        navigationEnv.getUpdateBy())
                // 更新时间
                .eq(navigationEnv.getGmtModified() != null, NavigationEnv::getGmtModified,
                        navigationEnv.getGmtModified())
                // 备注
                .eq(!StringUtils.isEmpty(navigationEnv.getRemark()), NavigationEnv::getRemark,
                        navigationEnv.getRemark())
                // 等级
                .eq(navigationEnv.getLv() != null, NavigationEnv::getLv, navigationEnv.getLv())
                .eq(StringUtils.hasLength(navigationEnv.getPlace()), NavigationEnv::getPlace, navigationEnv.getPlace());

        IPage<NavigationEnv> page = page(MPageUtils.mpPage(), queryWrapper);
        return page;
    }

    @Override
    public List<NavigationEnv> envList() {
       return mapper.selectJoinList(NavigationEnv.class,
                JoinWrappers.lambda(NavigationEnv.class)
                        .select(NavigationEnv::getId, NavigationEnv::getName, NavigationEnv::getEnvType,
                                NavigationEnv::getEnvTypeId, NavigationEnv::getGroup, NavigationEnv::getPlace)
                        .leftJoin(NavigationEnvType.class, NavigationEnvType::getId,
                                NavigationEnv::getEnvTypeId)
                        .eq(NavigationEnvType::getIsFence, true));
    }
    /**
     * 通航环境详情
     *
     * @param id
     * @return
     */
    @Override
    public NavigationEnv info(Long id) {
        return getById(id);
    }

    /**
     * 通航环境新增
     *
     * @param navigationEnv 根据需要进行传值
     * @return
     */
    @Override
    public boolean add(NavigationEnv navigationEnv) {
        if (envTypeMapper.selectById(navigationEnv.getEnvTypeId()) == null) {
            throw new ServiceException("请选择通航环境类型");
        }
        boolean save = save(navigationEnv);
        if (save) {
            delCacheEnv(navigationEnv);
        }
        return save;
    }


    /**
     * 通航环境修改
     *
     * @param navigationEnv 根据需要进行传值
     * @return
     */
    @Override
    public boolean modify(NavigationEnv navigationEnv) {
        boolean update = updateById(navigationEnv);
        if (update) {
            delCacheEnv(navigationEnv);
        }
        return update;
    }

    /**
     * 通航环境删除(单个条目)
     *
     * @param id
     * @return
     */
    @Override
    public boolean remove(Integer id) {
        NavigationEnv one = getOne(Wrappers.<NavigationEnv>lambdaQuery().select(NavigationEnv::getEnvType).eq(NavigationEnv::getId, id));
        boolean remove = removeById(id);
        if (remove){
            delCacheEnv(one);
        }
        return remove;
    }

    /**
     * 通航环境删除(多个条目)
     *
     * @param ids
     * @return
     */
    @Override
    public boolean removes(List<Integer> ids) {
        boolean remove = removeByIds(ids);
        if (remove){
            envAreas.forEach(env -> {
                delCacheEnv(env);
            });
        }
        return remove;
    }

    public static List<String> envAreas = Arrays.asList(Constants.ONE_WARNING, Constants.TWO_WARNING,
            Constants.THREE_WARNING,
            Constants.MONITORING,
            Constants.SHIPPING_LANE,
            Constants.HARBOR,
            Constants.ANCHORAGE_GROUND);
    /**
     * 查询所有有规则并且启用的预警区
     *
     * @return
     */
    @Override
    public List<InnerNavigationEnvVo> getEnvAndRulelist() {
        List<InnerNavigationEnvVo> envList = mapper.getEnvList();
        for (InnerNavigationEnvVo envVo : envList) {
            envVo.setRules(ruleMapper.selectList(Wrappers.<EarlyWarningRule>lambdaQuery().eq(EarlyWarningRule::getEnvId, envVo.getId())
                    .eq(EarlyWarningRule::getStatus, true)));
        }
        return envList;
    }

    private void delCacheEnv(String envType) {
        if (StringUtils.hasLength(envType)) {
            redisUtil.del(getEnvKey(envType));
            insertEnv2Redis(envType);
        }
    }
    private void delCacheEnv(NavigationEnv navigationEnv) {
        if(navigationEnv != null)
        delCacheEnv(navigationEnv.getEnvType());
    }

    public void insertEnv2Redis(String envType) {
        List<NavigationEnv> navigationEnvs = mapper.selectJoinList(NavigationEnv.class,
                JoinWrappers.lambda(NavigationEnv.class)
                        .select(NavigationEnv::getId, NavigationEnv::getName, NavigationEnv::getEnvType,
                                NavigationEnv::getEnvTypeId,
                                NavigationEnv::getRegions, NavigationEnv::getGroup, NavigationEnv::getPlace)
                        .leftJoin(NavigationEnvType.class, NavigationEnvType::getId,
                                NavigationEnv::getEnvTypeId)
                        .eq(NavigationEnvType::getIsFence, true)
                        .eq(NavigationEnvType::getEnvKey, envType));

        Map<String, List<EnvDto>> map = new HashMap<>();
        navigationEnvs.forEach(nav -> {
            EnvDto envDto = new EnvDto();
            BeanUtils.copyProperties(nav, envDto);
            List<EnvDto> envDtos = map.get(nav.getGroup());
            if (envDtos == null) {
                envDtos = new ArrayList<>();
                envDtos.add(envDto);
                map.put(nav.getGroup(), envDtos);
            } else {
                envDtos.add(envDto);
            }
        });
        map.forEach((k, v) ->
                redisUtil.hmSet(getEnvKey(envType), k, v)
        );
    }

    public String getEnvKey(String key) {
        return getEnvKey(key, null);
    }

    public String getEnvKey(String key, String group) {
        if (org.apache.commons.lang3.StringUtils.isBlank(group)) {
            return Constants.ENV_AREA + key;
        }
        return Constants.ENV_AREA + key + ":" + group;
    }
}
